(* ::Package:: *)

(************************************************************************)
(* This file was generated automatically by the Mathematica front end.  *)
(* It contains Initialization cells from a Notebook file, which         *)
(* typically will have the same name as this file except ending in      *)
(* ".nb" instead of ".m".                                               *)
(*                                                                      *)
(* This file is intended to be loaded into the Mathematica kernel using *)
(* the package loading commands Get or Needs.  Doing so is equivalent   *)
(* to using the Evaluate Initialization Cells menu command in the front *)
(* end.                                                                 *)
(*                                                                      *)
(* DO NOT EDIT THIS FILE.  This entire file is regenerated              *)
(* automatically each time the parent Notebook file is saved in the     *)
(* Mathematica front end.  Any changes you make to this file will be    *)
(* overwritten.                                                         *)
(************************************************************************)



BeginPackage["W`KNN`"];
KNN::usage="KNN classifier";

K::usage="number of neighbor";
Distancef::usage="";


Begin["`PP`"];


Options[KNN]={K->4,Distancef->EuclideanDistance};
(*KNN classifier*)
(*data,temp and tg should all flattened first*)
(*tg also has (0,1) form*)(*the result group is a (0,1) confusion matrix which can use 2-class VF, but Knn chooses only one class for each data, so FA==fr, only False reject rate has actual meaning*)
KNN[data_,tmp_,tg_,opts___]:=Module[
{df,group,i,j,k,lk,ng,nf,pg},
If[Length[data[[1]]]!=Length[tmp[[1]]]\[Or]Length[tmp]!=Length[tg],Print["input data dimensions error"];Return[]];(* distance metrics*)
df=Distancef/.{opts}/.Options[KNN];
(* number of n*)
k=K/.{opts}/.Options[KNN];
(*how many tmp in each class do we have and k must not be larger than the smallest one*)
lk=Min[Total[tg]];

(*If[lk<k,Print["k too big, must smaller than sample"];Return[]];*)
(*less strict*)
If[lk<k,Print["Warning: k is bigger than num of samples in a class"]];
(*ng=Length[Union[tg]];*)
ng=Length[tg[[1]]];(*column of tg is num of classes*)
group=ConstantArray[0,{Length[data],ng}];
(*Print[ng,Length[data]];*)
(*using this function we can easily fing nearest neighbours*)
nf=Nearest[tmp->tg,DistanceFunction->df];
(*ctmp={tmp,tg}\[Transpose];*)
For[i=1,i<=Length[data],i++,
pg=Commonest[nf[data[[i]],k]];
(*Print[pg];*)
(*usually length of pg should be 1,but if more than 1,the nearest one counts*)
group[[i]]=pg[[1]];
];
group
];


End[];
EndPackage[];



